{
 *  Copyright (c) 2012 Andrey Kemka
 *
 *  This software is provided 'as-is', without any express or
 *  implied warranty. In no event will the authors be held
 *  liable for any damages arising from the use of this software.
 *
 *  Permission is granted to anyone to use this software for any purpose,
 *  including commercial applications, and to alter it and redistribute
 *  it freely, subject to the following restrictions:
 *
 *  1. The origin of this software must not be misrepresented;
 *     you must not claim that you wrote the original software.
 *     If you use this software in a product, an acknowledgment
 *     in the product documentation would be appreciated but
 *     is not required.
 *
 *  2. Altered source versions must be plainly marked as such,
 *     and must not be misrepresented as being the original software.
 *
 *  3. This notice may not be removed or altered from any
 *     source distribution.
}
unit zgl_log;

{$I zgl_config.cfg}

interface
uses
  zgl_file;

procedure log_Init;
procedure log_Close;
procedure log_Add( const Message : UTF8String; Timings : Boolean = TRUE );
procedure log_Flush;
function  log_Timing : UTF8String;

var
  log      : zglTFile = FILE_ERROR;
  logStart : LongWord;
  logFile  : PAnsiChar;

implementation
uses
  zgl_application,
  zgl_main,
  zgl_timers,
  zgl_utils;

procedure log_Init;
  var
    i  : Integer;
    es : UTF8String;
begin
  if ( appFlags and APP_USE_LOG = 0 ) Then exit;
  if log <> FILE_ERROR Then exit;
  appLog   := TRUE;
  logStart := Round( timer_GetTicks() );

  {$IFDEF LINUX}
  if not Assigned( logFile ) Then
    logFile := utf8_GetPAnsiChar( 'log.txt' )
  {$ENDIF}
  {$IFDEF WINDOWS}
  if not Assigned( logFile ) Then
    logFile := utf8_GetPAnsiChar( 'log.txt' )
  {$ENDIF}
  {$IFDEF MACOSX}
  if not Assigned( logFile ) Then
    logFile := utf8_GetPAnsiChar( appWorkDir + '../log.txt' )
  {$ENDIF}
  {$IFDEF iOS}
  if not Assigned( logFile ) Then
    logFile := utf8_GetPAnsiChar( appHomeDir + 'log.txt' )
  {$ENDIF}
  else
    logFile := utf8_GetPAnsiChar( logFile );

  {$IFNDEF ANDROID}
  file_Open( log, logFile, FOM_CREATE );
  {$ENDIF}
  // crazy code :)
  es := '';
  for i := 0 to Length( cs_ZenGL + ' (' + cs_Date + ')' ) + 7 do
    es := es + '=';
  log_Add( es, FALSE );
  log_Add( '=== ' + cs_ZenGL + ' (' + cs_Date + ') ===', FALSE );
  log_Add( es, FALSE );
  log_Add( 'Begin' );
end;

procedure log_Close;
begin
  appLog := FALSE;
  FreeMem( logFile );
  logFile := nil;

  if log <> FILE_ERROR Then
    file_Close( log );
end;

procedure log_Add( const Message : UTF8String; Timings : Boolean = TRUE );
  var
    str : UTF8String;
begin
  if not appLog Then exit;
  {$IF ( DEFINED(LINUX) or DEFINED(iOS) ) and ( not DEFINED(ANDROID) )}
  if ( appLog ) and ( Pos( 'ERROR: ', Message ) = 0 ) and ( Pos( 'WARNING: ', Message ) = 0 ) Then
    printf( PAnsiChar( Message + #10 ), [ nil ] );
  {$IFEND}
  if Timings Then
    str := log_Timing + Message + #13#10
  else
    str := Message + #13#10;

  {$IFNDEF ANDROID}
  file_Write( log, str[ 1 ], Length( str ) );
  {$ELSE}
  __android_log_write( 3, 'ZenGL', PAnsiChar( log_Timing + Message ) );
  {$ENDIF}

  {$IFDEF USE_LOG_FLUSH}
  log_Flush();
  {$ENDIF}
end;

procedure log_Flush;
begin
  if log <> FILE_ERROR Then
    file_Flush( log );
end;

function log_Timing : UTF8String;
  var
    v : LongWord;
begin
  v := Round( timer_GetTicks() ) - logstart;
  case v of
    0..9:               Result := '[0000000' + u_IntToStr( v ) + 'ms] ';
    10..99:             Result := '[000000'  + u_IntToStr( v ) + 'ms] ';
    100..999:           Result := '[00000'   + u_IntToStr( v ) + 'ms] ';
    1000..9999:         Result := '[0000'    + u_IntToStr( v ) + 'ms] ';
    10000..99999:       Result := '[000'     + u_IntToStr( v ) + 'ms] ';
    100000..999999:     Result := '[00'      + u_IntToStr( v ) + 'ms] ';
    1000000..9999999:   Result := '[0'       + u_IntToStr( v ) + 'ms] ';
    10000000..99999999: Result := '['        + u_IntToStr( v ) + 'ms] ';
  else
    Result := '[00000000ms]';
  end;
end;

end.
